#ifndef MCMC_SW_H
#define MCMC_SW_H

#include "mcmcLayerRegion.h"
#include "mcmcModelSupervisor.h"

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class MCMC_SW_Sample_2Way
{
public:
	// construction & destruction
	MCMC_SW_Sample_2Way();
	~MCMC_SW_Sample_2Way();
	virtual void	Free(void);
	virtual void	ClearRecord(void);
	virtual void	Set(MCMC_Layer_Regions &graph, MCMC_ModelSupervisor &model_supervisor);

	// operators

	// access

	// operations

	virtual double	ProposeTwoCueTypes(int indexid_gregion);
	virtual double	QProposeTwoCueTypes(int indexid_gregion);
	virtual void	ExchangeCueValues(void);
	
	/////////
	virtual double	Propose(const int indexid, 
							LinkList<int> &list_proposed, int &cue_selected_comp_rt, int &indexid_nb_rt, LinkList<int> &list_leftover);

	virtual double	Q_ProposeBack(const int indexid_new1, const int indexid_new2);

	inline MCMC_Layer_Regions* LayerRegion(void){return player_region;};

protected:
	virtual void	ToComputeComingBack(const int indexid_new1, const int indexid_new2);

	virtual void	PrepareToCombineTwoCueTypes(int indexid_gregion);

	// bonds
	virtual bool	PrepareBonds(void);
	virtual void	SampleEdges(void);
	virtual double	QComponent(RF &rf_regions);
	virtual double	QCut(void);

	// for the selected connected component
	virtual bool	PrepareToProposeComponent(RF& rf_regions);
	virtual double	ProposeComponent(void);
	virtual void	FindConnectedComponent(const int indexid1);

	// neighbor
	virtual void	CompositeCuesWithNeighbors(LinkList<int> &list_region_nb, bool bpropose=true);
	virtual bool	PrepareToProposeNeighborAndCueType(bool bpropose=true);
	virtual double	ProposeNeighbor(int &indexid_nb1);
	virtual double  QProposeNeighbor(void);

public:
	int					cue_current,cue_other_tocombine,cue_4ccp;

protected:
	MCMC_Layer_Regions		*player_region;
	MCMC_ModelSupervisor	*pmodel_supervisor;

private:

	mcmcVector<char>		vc_sign_neighbors;
	RF					rf_cue_other;
	mcmcMatrix<char>		mx_sampled_edge;
	MCMC_CombinedAffinity	*p_cues_with_all_gregions;
	RF3D				rf_neighbor_and_cuetype;

	mcmcVector<int>			vc_involved_indexid;
	mcmcVector<int>			vc_involved_order_indexid;

	mcmcVector<int>			vc_nb_order_of_indexid;
	mcmcVector<int>			vc_nb_indexid;

	mcmcVector<char>		vc_flag_selected;
	LinkList<int>		list_selected;

	int					indexid_nb;
	int					num_cues;
};


/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class MCMC_SW_Cuts_2Way
{
public:
	// construction & destruction
	MCMC_SW_Cuts_2Way();
	~MCMC_SW_Cuts_2Way();

	virtual void	Set(MCMC_Layer_Regions &graph, MCMC_ModelSupervisor &model_supervisor);
	MCMC_Layer_Regions*	LayerRegion(void){return player_region;};

	// operoters
	virtual void	OneStep(void);
	virtual bool	TryAccept(void);
	virtual void	DoAction(void);

	virtual void	ClearShowProposal(void);
	
	virtual bool	IsAccepted(void){return baccept;};

protected:
	virtual double	QForRegion(const double crying_voice, const int num_aregions);
	virtual bool	PrepareToProposeGRegion(RF &rf_gregions);
	virtual double	ProposeAGRegion(int &indexid_gregion_selected);
	virtual double	Q_ProposeGRegion(int indexid_gregion_selected);
	
	virtual double	ProposeModels(const int cue_type);
	virtual double	Q_ProposeModel(const int indexid1, const int indexid2);
	
	virtual double	EnergyOldAndSave(void);

	virtual bool	UngroupAndGroup(int &indexid_withproposed, int &indexid_old,
									LinkList<int> &list_proposed, LinkList<int> &list_left, int indexid_nb);

public:
	char					Info[4][200];

protected:

	MCMC_Layer_Regions		*player_region;
	MCMC_ModelSupervisor	*pmodel_supervisor;
	MCMC_SW_Sample_2Way		sw_cut;
	RF						rf_gregions;
	MCMC_GRegion			gregion_buf1,gregion_buf2;
	
	int						indexid_tochange,indexid_nb;
	int						indexid_new1,indexid_new2;
	LinkList<int>			list_gregions_ccp,list_gregions_left;

	double					Q1_2,Q2_1;
	double					energy1,energy2;	
	bool					baccept;
};


#endif
